package com.beyondsoft.dtc.mobile.automation.util;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;

import com.beyondsoft.dtc.mobile.automation.base.GlobalConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Created by Robin on 1/28/2016.
 */
public class HttpUtil {
	private final static Logger logger = LoggerFactory
			.getLogger(HttpUtil.class);
	private static final String CRLF = "\r\n";

	private static String getResponseString(InputStream in) throws IOException {
		StringBuilder builder = new StringBuilder();
		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		String inputLine;

		while ((inputLine = reader.readLine()) != null) {
			builder.append(inputLine);
		}
		reader.close();
		return builder.toString();
	}

	public static String sendPOST(String urlString, String parameters,
			String token) throws Exception {

		HttpURLConnection conn = null;
		try {
			URL url = new URL(urlString);
			if (urlString.toLowerCase().startsWith("https")) {
				conn = (HttpsURLConnection) url.openConnection();
				conn.setConnectTimeout(30000);
				conn.setReadTimeout(30000);
				SSLContext sc = SSLContext.getInstance("SSL");
				sc.init(null,
						new TrustManager[] { new TrustSSL.TrustAnyTrustManager() },
						new java.security.SecureRandom());
				((HttpsURLConnection) conn).setSSLSocketFactory(sc
						.getSocketFactory());
				((HttpsURLConnection) conn)
						.setHostnameVerifier(new TrustSSL.TrustAnyHostnameVerifier());
			} else {
				conn = (HttpURLConnection) url.openConnection();
				conn.setConnectTimeout(30000);
				conn.setReadTimeout(30000);
			}

			if (!StringUtil.isEmpty(token)) {
				conn.setRequestProperty("Content-type", "application/json");
				conn.setRequestProperty("Authorization", "Bearer " + token);
			}

			// For POST only - START
			conn.setRequestMethod("POST");
			conn.setDoOutput(true);
			OutputStream os = conn.getOutputStream();
			os.write(parameters.getBytes(GlobalConstants.DEFAULT_ENCODE));
			os.flush();
			os.close();
			// For POST only - END

			int responseCode = conn.getResponseCode();
			logger.info("POST Response Code :: {}", responseCode);

			if (responseCode != HttpURLConnection.HTTP_OK
					&& responseCode != HttpURLConnection.HTTP_CREATED) {
				String result = "POST Response Code :: " + responseCode + ", "
						+ getResponseString(conn.getErrorStream());
				logger.warn("POST request not worked! error msg {}", result);
				throw new IOException(result);
			}
			return getResponseString(conn.getInputStream());

		} finally {
			try {
				if (conn != null) {
					conn.disconnect();
				}
			} catch (Exception e) {
			}
		}
	}

	//
	// public static String sendPOSTByHttps(String urlString, String parameters,
	// String token) throws Exception {
	// URL obj = new URL(urlString);
	// SSLContext sc = SSLContext.getInstance("SSL");
	// sc.init(null, new TrustManager[]{new TrustSSL.TrustAnyTrustManager()},
	// new java.security.SecureRandom());
	// HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
	// con.setSSLSocketFactory(sc.getSocketFactory());
	// con.setHostnameVerifier(new TrustSSL.TrustAnyHostnameVerifier());
	// con.setRequestMethod("POST");
	//
	// if (!StringUtil.isEmpty(token)) {
	// con.setRequestProperty("Content-type", "application/json");
	// con.setRequestProperty("Authorization", "Bearer " + token);
	// }
	//
	// // For POST only - START
	// con.setDoOutput(true);
	// OutputStream os = con.getOutputStream();
	// os.write(parameters.getBytes(GlobalConstants.DEFAULT_ENCODE));
	// os.flush();
	// os.close();
	// // For POST only - END
	//
	// int responseCode = con.getResponseCode();
	// logger.info(device.getConnectAddress() + " POST Response Code :: {}",
	// responseCode);
	//
	// if (responseCode != HttpURLConnection.HTTP_OK
	// && responseCode != HttpURLConnection.HTTP_CREATED) {
	// String result = getResponseString(con.getErrorStream());
	// logger.warn("POST request not worked! error msg {}", result);
	// throw new IOException(result);
	// }
	// return getResponseString(con.getInputStream());
	// }

	public static String fileUpload(String urlStr, String filePath, String token)
			throws Exception {
		// if (urlStr.toLowerCase().startsWith("https")) {
		// return fileUploadByHttps(urlStr, filePath, token);
		// }

		HttpURLConnection conn = null;
		String BOUNDARY = "---------------------------"
				+ System.currentTimeMillis();
		try {
			File file = new File(filePath);
			if (!file.exists()) {
				return "Error: file is not existed!";
			}
			String fileName = file.getName();

			URL url = new URL(urlStr);
			if (urlStr.toLowerCase().startsWith("https")) {
				SSLContext sc = SSLContext.getInstance("SSL");
				sc.init(null,
						new TrustManager[] { new TrustSSL.TrustAnyTrustManager() },
						new java.security.SecureRandom());
				conn = (HttpsURLConnection) url.openConnection();
				conn.setConnectTimeout(30000);
				conn.setReadTimeout(30000);
				((HttpsURLConnection) conn).setSSLSocketFactory(sc
						.getSocketFactory());
				((HttpsURLConnection) conn)
						.setHostnameVerifier(new TrustSSL.TrustAnyHostnameVerifier());
			} else {
				conn = (HttpURLConnection) url.openConnection();
				conn.setConnectTimeout(30000);
				conn.setReadTimeout(30000);
			}

			conn.setConnectTimeout(5000);
			conn.setReadTimeout(30000);
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type",
					"multipart/form-data; boundary=" + BOUNDARY);

			if (!StringUtil.isEmpty(token)) {
				conn.setRequestProperty("Authorization", "Bearer " + token);
			}

			StringBuilder builder = new StringBuilder();
			builder.append(CRLF).append("--").append(BOUNDARY).append(CRLF);
			builder.append("Content-Disposition: form-data; name=\"")
					.append(fileName).append("\"; filename=\"")
					.append(fileName).append("\"").append(CRLF);
			builder.append("Content-Type: application/octet-stream ")
					.append(CRLF).append(CRLF);

			OutputStream out = new DataOutputStream(conn.getOutputStream());
			out.write(builder.toString().getBytes(
					GlobalConstants.DEFAULT_ENCODE));

			DataInputStream in = new DataInputStream(new FileInputStream(file));
			int bytes = 0;
			byte[] bufferOut = new byte[8192];
			while ((bytes = in.read(bufferOut)) != -1) {
				out.write(bufferOut, 0, bytes);
			}
			in.close();

			byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
			out.write(endData);
			out.flush();
			out.close();

			int responseCode = conn.getResponseCode();
			logger.info("file POST Response Code :: {}", responseCode);

			if (responseCode != HttpURLConnection.HTTP_OK
					&& responseCode != HttpURLConnection.HTTP_CREATED) {
				String result = "file POST Response Code ::" + responseCode
						+ ", " + getResponseString(conn.getErrorStream());
				logger.warn("file POST request not worked! error msg {}",
						result);
				throw new IOException(result);
			}
			return getResponseString(conn.getInputStream());
		} finally {
			try {
				if (conn != null) {
					conn.disconnect();
				}
			} catch (Exception e) {
			}
		}
	}

	//
	// public static String fileUploadByHttps(String urlStr, String filePath,
	// String token) throws Exception {
	// HttpsURLConnection conn = null;
	// String BOUNDARY = "---------------------------" +
	// System.currentTimeMillis();
	// try {
	// File file = new File(filePath);
	// if (!file.exists()) {
	// return "Error: file is not existed!";
	// }
	// String fileName = file.getName();
	//
	// URL url = new URL(urlStr);
	// SSLContext sc = SSLContext.getInstance("SSL");
	// sc.init(null, new TrustManager[]{new TrustSSL.TrustAnyTrustManager()},
	// new java.security.SecureRandom());
	// conn = (HttpsURLConnection) url.openConnection();
	// conn.setSSLSocketFactory(sc.getSocketFactory());
	// conn.setHostnameVerifier(new TrustSSL.TrustAnyHostnameVerifier());
	//
	// conn.setConnectTimeout(5000);
	// conn.setReadTimeout(30000);
	// conn.setDoOutput(true);
	// conn.setDoInput(true);
	// conn.setUseCaches(false);
	// conn.setRequestMethod("POST");
	// conn.setRequestProperty("Connection", "Keep-Alive");
	// conn.setRequestProperty("Content-Type", "multipart/form-data; boundary="
	// + BOUNDARY);
	//
	// if (!StringUtil.isEmpty(token)) {
	// conn.setRequestProperty("Authorization", "Bearer " + token);
	// }
	//
	// StringBuilder builder = new StringBuilder();
	// builder.append(CRLF).append("--").append(BOUNDARY).append(CRLF);
	// builder.append("Content-Disposition: form-data; name=\"").append(fileName).append("\"; filename=\"").append(fileName).append("\"").append(CRLF);
	// builder.append("Content-Type: application/octet-stream ").append(CRLF).append(CRLF);
	//
	// OutputStream out = new DataOutputStream(conn.getOutputStream());
	// out.write(builder.toString().getBytes(GlobalConstants.DEFAULT_ENCODE));
	//
	// DataInputStream in = new DataInputStream(new FileInputStream(file));
	// int bytes = 0;
	// byte[] bufferOut = new byte[8192];
	// while ((bytes = in.read(bufferOut)) != -1) {
	// out.write(bufferOut, 0, bytes);
	// }
	// in.close();
	//
	// byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
	// out.write(endData);
	// out.flush();
	// out.close();
	//
	// int responseCode = conn.getResponseCode();
	// logger.info(device.getConnectAddress() +
	// " file POST Response Code :: {}", responseCode);
	//
	// if (responseCode != HttpURLConnection.HTTP_OK
	// && responseCode != HttpURLConnection.HTTP_CREATED) {
	// String result = getResponseString(conn.getErrorStream());
	// logger.warn("file POST request not worked! error msg {}", result);
	// throw new IOException(result);
	// }
	// return getResponseString(conn.getInputStream());
	// } finally {
	// try {
	// if (conn != null) {
	// conn.disconnect();
	// }
	// } catch (Exception e) {
	// }
	// }
	// }

	public static void main(String[] args) throws Exception {
		String url = "http://10.23.0.65:7100/s/upload/apk";
		String file = "Game_SuperMary.apk";
		String token = "3535c1bb831041b68b197ad59fff49b26d054004b54a4d53913afd037e39fb74";
		logger.debug("File upload: {}", fileUpload(url, file, token));

		String storageUrl = "http://10.23.0.65:7100/";
		if (storageUrl.endsWith("/")) {
			storageUrl = storageUrl.substring(0, storageUrl.length() - 1);
		}
		logger.debug("storage url: [{}]", storageUrl);
	}
}
